package managedbean;

import entity.IndicativeProductPrice;
import entity.PurchaseOrder;
import entity.PurchaseOrderItem;
import entity.Quotation;
import entity.SalesOrder;
import entity.SalesOrderItem;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import session.IndicativeProductPriceManager;
import session.PurchaseOrderManager;
import session.QuotationManager;
import session.SalesOrderManager;

@SessionScoped
@ManagedBean
public class SalesOrderBean {

    @EJB
    private SalesOrderManager salesOrderManager;
    @EJB
    private IndicativeProductPriceManager productManager;
    @EJB
    private PurchaseOrderManager purchaseOrderManager;
    @EJB
    private QuotationManager quotationManager;
    private Long salesOrderId;
    private String productName;
    private Integer numOfProduct;
    private Double productPrice;
    private Double totalPrice;
    private Integer confirmedLeadTime; //in days; dummy value for 1st release
    private Timestamp dateOrdered;
    private String shippingAddress;
    private String lastModifiedBy;
    private String status; //To update at each stage of production
    private Long purchaseOrderId;
    private Collection<SalesOrderItem> salesOrderItemList = new ArrayList<SalesOrderItem>();
    private Collection<SalesOrder> salesOrderList = new ArrayList<SalesOrder>();
    private Collection<PurchaseOrder> purchaseOrderList = new ArrayList<PurchaseOrder>();
    private Collection<PurchaseOrderItem> purchaseOrderItemList = new ArrayList<PurchaseOrderItem>();
    private Collection<IndicativeProductPrice> productList = new ArrayList<IndicativeProductPrice>();
    private boolean matches; //if quotation matches with purchase order
    private Long indicativeProductPriceId;
    private SalesOrder salesOrder;
    //Creates a new instance of SalesOrderBean

    public SalesOrderBean() {
        totalPrice = 0.0;
    }

    public void addNewSalesOrder(ActionEvent event) {
//get the Purchase Order of this purchaseOrderId
        PurchaseOrder p = purchaseOrderManager.getPurchaseOrder(purchaseOrderId);

        salesOrderManager.createSalesOrder(p.getId());
        dateOrdered = salesOrderManager.getSalesOrder().getDateOrdered();
        status=salesOrderManager.getSalesOrder().getStatus();
        lastModifiedBy=salesOrderManager.getSalesOrder().getLastModifiedBy();
        for (Object o : p.getPurchaseOrderItems()) {
            SalesOrderItem tempSalesOrderItem = new SalesOrderItem();
            PurchaseOrderItem tempPurchaseOrderItem = (PurchaseOrderItem) o;
            tempSalesOrderItem.setNumOfProduct(tempPurchaseOrderItem.getNumOfProduct());
            tempSalesOrderItem.setProductName(tempPurchaseOrderItem.getProductName());
            tempSalesOrderItem.setProductPrice(tempPurchaseOrderItem.getProductPrice());
            tempSalesOrderItem.setShippingAddress(tempPurchaseOrderItem.getShippingAddress());
            salesOrderItemList.add(tempSalesOrderItem);
        }
        calculateTotalPrice(); //get the total price
    }

    public void finaliseSalesOrder(ActionEvent event) { //TODO: CHECK IF CORRECT
        salesOrderManager.addSalesOrderItem(salesOrderItemList);
        salesOrderManager.persist();
        salesOrderId = salesOrderManager.getSalesOrder().getId();
    }

    public void confirmNewSalesOrder(ActionEvent event) {
        getSalesOrderManager().persist();
        setSalesOrderId(getSalesOrderManager().getSalesOrder().getId());
    }

    public void retrievePurchaseOrderList(ActionEvent event) {
        purchaseOrderList = purchaseOrderManager.getPurchaseOrderList();
    }

    public void updateSalesOrderStatus(ActionEvent event) {
        getSalesOrderManager().updateSalesOrderStatus(salesOrderId, status);
    }

    public void updateSalesOrderLastModifiedBy(ActionEvent event) {
        getSalesOrderManager().updateSalesOrderLastModifiedBy(salesOrderId, lastModifiedBy);
    }

    public void calculateTotalPrice(ActionEvent event) {
        for (Object o : salesOrderItemList) {
            PurchaseOrderItem tempPurchaseOrderItem = new PurchaseOrderItem();
            tempPurchaseOrderItem = (PurchaseOrderItem) o;
            totalPrice += (tempPurchaseOrderItem.getNumOfProduct() * tempPurchaseOrderItem.getProductPrice());
        }
    }

    public void getClientSalesOrderList(ActionEvent event) {
        //COMMENT OFF UNTIL INTEGRATION, UNTESTED CODE (Samuel's code)
        //String username  = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user");
        // c = quotationManager.getClient(username);

        String user = "SystemUser"; //get username from session
        salesOrderList = salesOrderManager.getSalesOrderList(user);
    }

    public void viewSalesOrder(ActionEvent event) {
        SalesOrder sales = salesOrderManager.getSalesOrder(salesOrderId.longValue());
        setSalesOrderId(sales.getId());
        setDateOrdered(sales.getDateOrdered());
        setConfirmedLeadTime(sales.getConfirmedLeadTime());
        setTotalPrice(sales.getTotalPrice());
        setLastModifiedBy(sales.getLastModifiedBy());
        setStatus(sales.getStatus());
        setSalesOrderItemList(sales.getSalesOrderItemList());
        salesOrderList.add(sales);
    }

    public void checkPurchaseOrder(ActionEvent event) {
        //get the Purchase Order of this purchaseOrderId
        PurchaseOrder p = purchaseOrderManager.getPurchaseOrder(purchaseOrderId);
        //get the Quotation of this Purchase Order
        Quotation q = quotationManager.getQuotation(p.getQuotationId());

        matches = purchaseOrderManager.matchQuotationPurchaseOrder(p, q, p.getPurchaseOrderItems(), q.getQuotationItems());
        if (matches == true) { //if matches, retrieve the list of purhcase order items to display later
            setPurchaseOrderItemList(purchaseOrderManager.getPurchaseOrderItemList(purchaseOrderId));
        }
    }

    public void resetItem(ActionEvent event) {
        this.setPurchaseOrderId(null);
        this.setProductPrice(null);
        this.setNumOfProduct(null);
    }

    public void resetAll(ActionEvent event) {
        this.setSalesOrderId(null);
        this.setNumOfProduct(null);
        this.setProductPrice(null);
        this.setConfirmedLeadTime(null);
        this.setDateOrdered(null);
        this.setShippingAddress(null);
        this.setSalesOrderItemList(null);
        this.setSalesOrderList(null);
        this.setPurchaseOrderId(null);
        this.setPurchaseOrderItemList(null);
        this.setPurchaseOrderItemList(null);
    }

    public void retrieveSalesOrderList(ActionEvent event) {
        salesOrderList = salesOrderManager.getSalesOrderList();
    }

    public void convertToSalesOrder(ActionEvent event) {
        System.out.println("Purchase Id: " + purchaseOrderId); //TEST
        Long quotationId = purchaseOrderManager.getPurchaseOrder(purchaseOrderId).getQuotationId(); //get quotationId of this purchase order
        salesOrderManager.createSalesOrder(quotationId); //create a new sales order
        salesOrderManager.persist(); //write to DB
    }

    public void viewQuotation(ActionEvent event) {
        salesOrder = salesOrderManager.getSalesOrder(salesOrderId);
    }

    public void calculateTotalPrice() {
        for (Object o : salesOrderItemList) {
            SalesOrderItem tempSalesOrderItem = new SalesOrderItem();
            tempSalesOrderItem = (SalesOrderItem) o;
            totalPrice += (tempSalesOrderItem.getNumOfProduct() * tempSalesOrderItem.getProductPrice());
        }
    }

    public void retrieveProductList() {
        productList = salesOrderManager.getProductList();
    }

    public void retrievePurchaseOrderItemList() {
        purchaseOrderItemList = purchaseOrderManager.getPurchaseOrderItem();
    }

    /**
     * @return the salesOrderManager
     */
    public SalesOrderManager getSalesOrderManager() {
        return salesOrderManager;
    }

    /**
     * @param salesOrderManager the salesOrderManager to set
     */
    public void setSalesOrderManager(SalesOrderManager salesOrderManager) {
        this.salesOrderManager = salesOrderManager;
    }

    /**
     * @return the salesOrderId
     */
    public Long getSalesOrderId() {
        return salesOrderId;
    }

    /**
     * @param salesOrderId the salesOrderId to set
     */
    public void setSalesOrderId(Long salesOrderId) {
        this.salesOrderId = salesOrderId;
    }

    /**
     * @return the numOfProduct
     */
    public Integer getNumOfProduct() {
        return numOfProduct;
    }

    /**
     * @param numOfProduct the numOfProduct to set
     */
    public void setNumOfProduct(Integer numOfProduct) {
        this.numOfProduct = numOfProduct;
    }

    /**
     * @return the productPrice
     */
    public Double getProductPrice() {
        return productPrice;
    }

    /**
     * @param productPrice the productPrice to set
     */
    public void setProductPrice(Double productPrice) {
        this.productPrice = productPrice;
    }

    /**
     * @return the confirmedLeadTime
     */
    public Integer getConfirmedLeadTime() {
        return confirmedLeadTime;
    }

    /**
     * @param confirmedLeadTime the confirmedLeadTime to set
     */
    public void setConfirmedLeadTime(Integer confirmedLeadTime) {
        this.confirmedLeadTime = confirmedLeadTime;
    }

    /**
     * @return the dateOrdered
     */
    public Timestamp getDateOrdered() {
        return dateOrdered;
    }

    /**
     * @param dateOrdered the dateOrdered to set
     */
    public void setDateOrdered(Timestamp dateOrdered) {
        this.dateOrdered = dateOrdered;
    }

    /**
     * @return the salesOrderItemList
     */
    public Collection<SalesOrderItem> getSalesOrderItem() {
        return salesOrderItemList;
    }

    /**
     * @param salesOrderItemList the salesOrderItemList to set
     */
    public void setSalesOrderItem(Collection<SalesOrderItem> salesOrderItemList) {
        this.salesOrderItemList = salesOrderItemList;
    }

    /**
     * @return the salesOrderList
     */
    public Collection<SalesOrder> getSalesOrderList() {
        return salesOrderList;
    }

    /**
     * @param salesOrderList the salesOrderList to set
     */
    public void setSalesOrderList(Collection<SalesOrder> salesOrderList) {
        this.salesOrderList = salesOrderList;
    }

    public String getShippingAddress() {
        return shippingAddress;
    }

    public void setShippingAddress(String address) {
        shippingAddress = address;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getLastModifiedBy() {
        return lastModifiedBy;
    }

    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }

    /**
     * @return the productManager
     */
    public IndicativeProductPriceManager getProductManager() {
        return productManager;
    }

    /**
     * @param productManager the productManager to set
     */
    public void setProductManager(IndicativeProductPriceManager productManager) {
        this.productManager = productManager;
    }

    /**
     * @return the productList
     */
    public Collection<IndicativeProductPrice> getProductList() {
        return productList;
    }

    /**
     * @param productList the productList to set
     */
    public void setProductList(Collection<IndicativeProductPrice> productList) {
        this.productList = productList;
    }

    /**
     * @return the purchaseOrderId
     */
    public Long getPurchaseOrderId() {
        return purchaseOrderId;
    }

    /**
     * @param purchaseOrderId the purchaseOrderId to set
     */
    public void setPurchaseOrderId(Long purchaseOrderId) {
        this.purchaseOrderId = purchaseOrderId;
    }

    /**
     * @return the productName
     */
    public String getProductName() {
        return productName;
    }

    /**
     * @param productName the productName to set
     */
    public void setProductName(String productName) {
        this.productName = productName;
    }

    public Collection<SalesOrderItem> getSalesOrderItemList() {
        return salesOrderItemList;
    }

    public void setSalesOrderItemList(Collection<SalesOrderItem> salesOrderItemList) {
        this.salesOrderItemList = salesOrderItemList;
    }

    public Collection<PurchaseOrderItem> getPurchaseOrderItemList() {
        return purchaseOrderItemList;
    }

    public void setPurchaseOrderItemList(Collection<PurchaseOrderItem> purchaseOrderItemList) {
        this.purchaseOrderItemList = purchaseOrderItemList;
    }

    public PurchaseOrderManager getPurchaseOrderManager() {
        return purchaseOrderManager;
    }

    public void setPurchaseOrderManager(PurchaseOrderManager purchaseOrderManager) {
        this.purchaseOrderManager = purchaseOrderManager;
    }

    public Collection<PurchaseOrder> getPurchaseOrderList() {
        return purchaseOrderList;
    }

    public void setPurchaseOrderList(Collection<PurchaseOrder> purchaseOrderList) {
        this.purchaseOrderList = purchaseOrderList;
    }

    public QuotationManager getQuotationManager() {
        return quotationManager;
    }

    public void setQuotationManager(QuotationManager quotationManager) {
        this.quotationManager = quotationManager;
    }

    public void setMatches(boolean matches) {
        this.matches = matches;
    }

    public boolean getMatches() {
        return matches;
    }

    public Double getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(Double totalPrice) {
        this.totalPrice = totalPrice;
    }

    public Long getIndicativeProductPriceId() {
        return indicativeProductPriceId;
    }

    public void setIndicativeProductPriceId(Long indicativeProductPriceId) {
        this.indicativeProductPriceId = indicativeProductPriceId;
    }

    public SalesOrder getSalesOrder() {
        return salesOrder;
    }

    public void setSalesOrder(SalesOrder salesOrder) {
        this.salesOrder = salesOrder;
    }
}
